/*
*	Copyright (C) 2014  Julio Montes, Mario Carrillo
*	
*	Julio Montes e-mail: imc.coder@gmail.com 
*
*	Mario Carrillo e-mail: mario_90ago@live.com.mx
*
*	BSD 3-Clause License
*/

#include "alliance/include/buildoptionsdlg.h"

#include "alliance/include/toolpanel.h"
#include "alliance/include/path.h"
#include "alliance/include/project.h"
#include "alliance/include/projectmgr.h"

#include "sdk/include/util.h"

#include <wx/dir.h>

namespace alliance
{
    wxArrayString BuildOptionsDialog::s_arrayDirectoryFiles;
    wxArrayString BuildOptionsDialog::s_arrayProjectFiles;

    BuildOptionsDialog::BuildOptionsDialog( wxWindow *parent, Project *project )
        : wxDialog( parent, wxID_ANY, wxT( "Build options" ), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER )
        , m_project( NULL )
        , m_flagAdd( false )
        , m_flagRemove( false )
    {
        m_project = project;

        s_arrayDirectoryFiles.Clear();
        s_arrayProjectFiles.Clear();

        wxArrayString arrayFiles;
        wxDir::GetAllFiles( project->GetDirectory(), &arrayFiles, wxEmptyString, wxDIR_FILES );
        for( size_t i=0; i<arrayFiles.Count(); ++i )
        {
            if( !arrayFiles[i].EndsWith( wxT( "." ) + ProjectManager::s_projectExtension ) )
            {
                s_arrayDirectoryFiles.Add( arrayFiles[i].AfterLast( _T( '/' ) ) );
            }
        }
        const std::vector<projectFile> &vectorFiles = project->GetFiles();
        for( size_t i=0; i<vectorFiles.size(); ++i )
        {
            const wxString &filename = vectorFiles[i].filename.AfterLast( _T( '/' ) );
            if( wxNOT_FOUND == s_arrayDirectoryFiles.Index( filename ) )
            {
                s_arrayProjectFiles.Add( filename );
            }
        }

        wxBoxSizer *sizer = new wxBoxSizer( wxVERTICAL );
        m_notebook = new wxNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_LEFT );
        sizer->Add( m_notebook, 1, wxEXPAND | wxTOP | wxLEFT | wxRIGHT, 10 );
        sizer->AddSpacer( 10 );

        wxBoxSizer *bsButtons = new wxBoxSizer( wxHORIZONTAL );
        wxButton *btnAdd = new wxButton( this, wxID_ADD );
        wxButton *btnRemove = new wxButton( this, wxID_REMOVE );
        wxButton *btnCancel = new wxButton( this, wxID_CANCEL );
        wxButton *btnOk = new wxButton( this, wxID_OK );
        bsButtons->Add( btnAdd );
        bsButtons->AddSpacer( 10 );
        bsButtons->Add( btnRemove );
        bsButtons->AddSpacer( 30 );
        bsButtons->Add( btnCancel );
        bsButtons->AddSpacer( 10 );
        bsButtons->Add( btnOk );
        sizer->Add( bsButtons, 0, wxALIGN_RIGHT | wxRIGHT, 10 );
        sizer->AddSpacer( 10 );

        Connect( wxID_ADD, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BuildOptionsDialog::OnAdd ) );
        Connect( wxID_REMOVE, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BuildOptionsDialog::OnRemove ) );
        Connect( wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BuildOptionsDialog::OnOk ) );
        Connect( wxID_ANY, wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, wxNotebookEventHandler( BuildOptionsDialog::OnPageChanged ) );
        Connect( wxID_ANY, wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING, wxNotebookEventHandler( BuildOptionsDialog::OnPageChanging ) );

        SetSizer( sizer );

        int x, y, w, h;
        wxClientDisplayRect( &x, &y, &w, &h);
        SetSize( w*0.85, h );

        LoadTools();
    }

    BuildOptionsDialog::~BuildOptionsDialog()
    {
        s_arrayDirectoryFiles.Clear();
        s_arrayProjectFiles.Clear();
    }

    void BuildOptionsDialog::LoadTools()
    {
        const std::vector<Tool> &tools = m_project->GetTools();
        for( size_t i=0; i<tools.size(); ++i )
        {
            ToolPanel *toolPanel = new ToolPanel( m_notebook, wxID_ANY );
            toolPanel->LoadTool( tools[i] );
            m_flagAdd = true;
            m_notebook->AddPage( toolPanel, toolPanel->GetCommand(), true );
        }
    }

    void BuildOptionsDialog::OnOk( wxCommandEvent &evt )
    {
        //first check if all panel are ok
        for( size_t i=0; i<m_notebook->GetPageCount(); ++i )
        {
            ToolPanel *toolPanel = dynamic_cast<ToolPanel *>( m_notebook->GetPage( i ) );
            if( !toolPanel->IsOk() )
            {
                m_notebook->SetSelection( i );
                return;
            }
        }

        //add all tools
        m_project->RemoveAllTools();
        for( size_t i=0; i<m_notebook->GetPageCount(); ++i )
        {
            ToolPanel *toolPanel = dynamic_cast<ToolPanel *>( m_notebook->GetPage( i ) );
            m_project->AddTool( toolPanel->GetTool() );
        }

        EndModal( wxID_OK );
    }

    void BuildOptionsDialog::OnAdd( wxCommandEvent &evt )
    {
        AddToolDialog dlg( this );
        if( dlg.ShowModal() != wxID_OK )
        {
            return;
        }

        const wxString &tool = dlg.GetTool();
        if( tool.IsEmpty() )
        {
            LOGD( wxT( "tool is empty" ) );
            return;
        }

        const wxString toolFilePath = Path::s_dirTools + tool + _T( "." ) + ToolPanel::s_fileExtensionTool;
        if( !wxFileExists( toolFilePath ) )
        {
            LOGD( toolFilePath + wxT( " not exists" ) );
            return;
        }

        ToolPanel *toolPanel = new ToolPanel( m_notebook, wxID_ANY );
        if( !toolPanel->LoadFile( toolFilePath ) )
        {
            LOGD( wxT( "cannot load file" ) + toolFilePath );
            toolPanel->Destroy();
            return;
        }
        m_flagAdd = true;
        m_notebook->AddPage( toolPanel, tool, true );
    }

    void BuildOptionsDialog::OnRemove( wxCommandEvent &evt )
    {
        if( m_notebook->GetPageCount() > 0 )
        {
            m_flagRemove = true;
            m_notebook->DeletePage( m_notebook->GetSelection() );
        }
    }

    void BuildOptionsDialog::OnPageChanging( wxNotebookEvent &evt )
    {
        if( m_flagAdd || m_flagRemove )
        {
            return;
        }

        const int oldSelection = evt.GetOldSelection();
//        if( oldSelection != -1 )
//        {
            ToolPanel *toolPanel = dynamic_cast<ToolPanel *>( m_notebook->GetPage( oldSelection ) );
            if( !toolPanel->OnPageChanging() )
            {
                evt.Veto();
            }
//        }
    }

    void BuildOptionsDialog::OnPageChanged( wxNotebookEvent &evt )
    {
        wxArrayString arrayFiles;
        int selection = evt.GetSelection();
        ToolPanel *toolPanel = NULL;
        for( int i=0; i<selection; ++i )
        {
            toolPanel = dynamic_cast<ToolPanel *>( m_notebook->GetPage( i ) );
            toolPanel->AddFilesToArray( &arrayFiles );
        }

        if( m_flagRemove )
        {
            ++selection;
            if( selection >= (int)m_notebook->GetPageCount() )
            {
                return;
            }
        }

        toolPanel = dynamic_cast<ToolPanel *>( m_notebook->GetPage( selection ) );

        if( !toolPanel->OnPageChanged( arrayFiles ) )
        {
            evt.Veto();
        }

        m_flagAdd = false;
        m_flagRemove = false;

    }





    AddToolDialog::AddToolDialog( wxWindow *parent )
        : wxDialog( parent, wxID_ANY, wxT( "Add tool" ), wxDefaultPosition, wxSize( 300, 350 ) )
    {
        wxBoxSizer *sizer = new wxBoxSizer( wxVERTICAL );

        sizer->AddSpacer( 15 );

        wxStaticText *stTools = new wxStaticText( this, wxID_ANY, wxT( "Select a tool" ) );
        sizer->Add( stTools, 0, wxEXPAND | wxLEFT | wxRIGHT, 15 );

        sizer->AddSpacer( 5 );

        wxArrayString arrayFiles;
        wxDir::GetAllFiles( Path::s_dirTools, &arrayFiles, wxT( "*." ) + ToolPanel::s_fileExtensionTool, wxDIR_FILES );
        for( size_t i=0; i<arrayFiles.Count(); ++i )
            arrayFiles[i] = arrayFiles[i].AfterLast( _T( '/' ) ).BeforeLast( _T( '.' ) );

        m_listTools = new wxListBox( this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
            arrayFiles, wxLB_SINGLE | wxLB_SORT );
        sizer->Add( m_listTools, 1, wxEXPAND | wxLEFT | wxRIGHT, 15 );

        sizer->AddSpacer( 30 );

        wxBoxSizer *sizerButtons = new wxBoxSizer( wxHORIZONTAL );
        wxButton *btnCancel = new wxButton( this, wxID_CANCEL );
        wxButton *btnOk = new wxButton( this, wxID_OK );
        sizerButtons->Add( btnCancel, 1 );
        sizerButtons->AddSpacer( 10 );
        sizerButtons->Add( btnOk, 1 );
        sizer->Add( sizerButtons, 0, wxALIGN_RIGHT | wxRIGHT, 10 );

        sizer->AddSpacer( 15 );

        SetSizer( sizer );
    }

    AddToolDialog::~AddToolDialog()
    {

    }

    wxString AddToolDialog::GetTool() const
    {
        const int selection( m_listTools->GetSelection() );

        if( selection != wxNOT_FOUND )
        {
            return m_listTools->GetString( selection );
        }

        return wxEmptyString;
    }
}
